package cn.tedu.charging.device.service;

import cn.tedu.charging.common.pojo.param.GunStatusUpdateParam;
import cn.tedu.charging.common.pojo.vo.GunInfoVO;
import cn.tedu.charging.common.pojo.vo.StationInfoVO;
import cn.tedu.charging.common.pojo.po.ChargingGunInfoPO;
import cn.tedu.charging.common.pojo.po.ChargingStationPO;
import cn.tedu.charging.device.repository.GunRepository;
import cn.tedu.charging.device.repository.StationRepository;
import com.alibaba.nacos.common.utils.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.domain.geo.GeoLocation;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DeviceService{
    @Autowired
    private StationRepository stationRepository;
    @Autowired
    private GunRepository gunRepository;
    public List<StationInfoVO> nearStations(Double longitude, Double latitude, Double distance) {
        //充电站 附近查询功能一定是依赖redis redis目前 数据是空的,数据库有充电站 但是redis没有数据
        //直接调用仓储层,到redis中查询 vo返回
        GeoResults<RedisGeoCommands.GeoLocation<Integer>> results= stationRepository.nearStations(longitude, latitude, distance);
        //List<StationInfoVO> stationInfoVOS = stationRepository.nearStations(longitude, latitude, distance);
        List<GeoResult<RedisGeoCommands.GeoLocation<Integer>>> contents = results.getContent();
        List<StationInfoVO> vos=null;
        if (CollectionUtils.isNotEmpty(contents)){
            vos=contents.stream().map(content->{
                //当前是GeoResult对象
                StationInfoVO vo=new StationInfoVO();
                vo.setId(content.getContent().getName());
                vo.setStationLat(new BigDecimal(content.getContent().getPoint().getY()));
                vo.setStationLng(new BigDecimal(content.getContent().getPoint().getX()));
                vo.setDistance(new BigDecimal(content.getDistance().getValue()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue());
                ChargingStationPO station = stationRepository.getStationById(content.getContent().getName());
                vo.setStationName(station.getStationName());
                vo.setAddress(station.getAddress());
                vo.setStatus(station.getStationStatus());
                return vo;
            }).collect(Collectors.toList());

        }
        return  vos.stream()
                .sorted((vo1, vo2) -> Double.compare(vo1.getDistance(), vo2.getDistance()))
                .collect(Collectors.toList());
    }

    public StationInfoVO stationDetail(Integer id) {
        //将id查询 交给仓储层,业务层 不关心是从数据库来的 还是从缓存redis来的
        ChargingStationPO po=stationRepository.getStationById(id);
        List<ChargingGunInfoPO> pos=gunRepository.getByStationId(id);
        StationInfoVO stationInfoVO = po2vo(po);
        stationInfoVO.setGunInfos(pos2vos(pos));
        return stationInfoVO;
    }

    private List<GunInfoVO> pos2vos(List<ChargingGunInfoPO> pos) {
        return pos.stream().map(po->{
            GunInfoVO vo=new GunInfoVO();
            vo.setId(po.getId());
            vo.setGunName(po.getGunName());
            vo.setGunStatus(po.getGunStatus());
            vo.setGunType(po.getGunType());
            vo.setElectricity(po.getElectricity());
            return vo;
        }).collect(Collectors.toList());
    }

    private StationInfoVO po2vo(ChargingStationPO po) {
        //不涉及到 和中心点的距离 id stationName latitude longitude.
        StationInfoVO vo=new StationInfoVO();
        vo.setId(po.getId());
        vo.setStationLat(po.getStationLat());
        vo.setStationLng(po.getStationLng());
        vo.setStationName(po.getStationName());
        vo.setAddress(po.getAddress());
        log.info("po2vo:{}",po);
        //distance
        return vo;
    }

    public Boolean updateGunStatus(GunStatusUpdateParam param) {
        //1.使用gunId查询gun实体数据
        ChargingGunInfoPO chargingGunInfoPO = gunRepository.getById(param.getGunId());
        //2.判断一下 如果不空 才继续更新
        if (chargingGunInfoPO !=null){
            //update charging_gun_info set status=#{status} where id=#{gunId}
            //gunRepository.update().set("gun_status",param.getStatus()).eq("id",param.getGunId());
            ChargingGunInfoPO poParam=new ChargingGunInfoPO();//除了status和id以外 其他属性都是空
            poParam.setGunStatus(param.getStatus());
            poParam.setId(param.getGunId());
            boolean success = gunRepository.updateById(poParam);//会使用id属性做条件 其他非空字段拼接 set
            return success;
        }
        return false;
    }
}
